using System;
using Microsoft.SPOT;
using System.Net;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT.Input;
using Microsoft.SPOT.Touch;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Hardware;
using DeviceSolutions.SPOT.Hardware;

namespace HouseControl
{
    public class server
    {

        public static void startserver()
        {


            // Check if our Tahoe has Network interfaces in order to be able to create a connection or not
            if (Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces().Length < 1)
            {
                Debug.Print("No Active network interfaces. Bombing out.");
                Thread.CurrentThread.Abort();
            }

            // Then use the network interface
            Microsoft.SPOT.Net.NetworkInformation.NetworkInterface NI = Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0];
           

            #region Static IP code
            // Enabling Sy=tatic IP adress
            NI.EnableStaticIP("192.168.2.104", "255.255.255.0", "192.168.2.1");
            Debug.Print("DCHP - IP Address = " + NI.IPAddress + " ... Net Mask = " + NI.SubnetMask + " ... Gateway = " + NI.GatewayAddress);
            #endregion

            // Create the socket            
            Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            // Bind the listening socket to the port
            IPAddress hostIP = IPAddress.Parse(NI.IPAddress);
            IPEndPoint ep = new IPEndPoint(hostIP, 80);
            listenSocket.Bind(ep);

            // Start listening
            listenSocket.Listen(1);

            // Main thread loop
            while (true)
            {
                Debug.Print("listening...");

                //Accept connection from anyone
                Socket newSock = listenSocket.Accept();
                //the actual client
                Debug.Print("Accepted a connection from " + newSock.RemoteEndPoint.ToString());

                

                // use the actual client
                using (newSock)
                {
                    // Get request from client and wait for 2 seconds to let him finish his request
                    if (newSock.Poll(2 * 1000000, SelectMode.SelectRead))
                    {
                        // Read bytes for request.
                        Byte[] buffer = new Byte[1024];
                        Int32 bytesRead = newSock.Receive(buffer);
                        // Split Request by "/","\n" and " " in order to well use after the request
                        String[] HTTPRequest = new String(Encoding.UTF8.GetChars(buffer)).Split(new char[] { '/', '\n', ' ' });

                        int k = HTTPRequest.Length;//length of the request
                        //some abstract variables that we will use 
                        bool container; 
                        bool container2;
                        bool container3;
                        double displayTemp;

                        for (int i = 0; i < k; i++)  //the request is an array or string so check each array
                        {
                            
                            if (HTTPRequest[i] == "database") //if we find database
                            {
                                DataBase.read_database();
                                string line="";   //help to read 
                                string container4;
                                for (int j = 0; j < Program.read_database.Length; j++)
                                {
                                     container4= Program.read_database[j]; //take one pant of the database 
                                     line = line + "\r\n" + container4; //add one pant to a true string and go to a new line before adding in order to separate clearly each event that happen
                                }
                                String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n" + line ; //put the database in a string
                                byte[] buffer1 = Encoding.UTF8.GetBytes(s);
                                int offset = 0;
                                int retour = 0;
                                int len = buffer1.Length;
                                while (len > 0)
                                {
                                    retour = newSock.Send(buffer1, offset, len, SocketFlags.None);//sending
                                    len -= retour;
                                    offset += retour;
                                }
                            }

                            if (HTTPRequest[i] == "checkdoorbell")  //if we find "checkdoorbell"
                            {
                                if (Program.gate == true) Program.door_bell_state = false; //turn off the door bell if the door is open 


                                if (Program.door_bell_state == true)
                                {
                                    //we send the state of the door bell 
                                    String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\ntrue";
                                    byte[] buffer1 = Encoding.UTF8.GetBytes(s);
                                    int offset = 0;
                                    int retour = 0;
                                    int len = buffer1.Length;
                                    while (len > 0)
                                    {
                                        retour = newSock.Send(buffer1, offset, len, SocketFlags.None); //sending 
                                        len -= retour;
                                        offset += retour;
                                    }
                                    Program.door_bell_state = false;
                                }
                                else if (Program.door_bell_state == false)
                                {
                                    //we send the new state of the door bell 
                                    String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n";
                                    byte[] buffer1 = Encoding.UTF8.GetBytes(s);
                                    int offset = 0;
                                    int retour = 0;
                                    int len = buffer1.Length;
                                    while (len > 0)
                                    {
                                        retour = newSock.Send(buffer1, offset, len, SocketFlags.None);
                                        len -= retour;
                                        offset += retour;
                                    }
                                
                                }
                            
                            
                            }

                            if (HTTPRequest[i] == "changelight0")  //if we find "changelight0"
                            {
                                //then we change the light in room 1
                                Program.stateLed = !Program.stateLed; 
                                Program.led.Write(Program.stateLed);
                                container = Program.stateLed;  //container will take the new value of the light in room 1

                                DataBase.android_user_add_light1_state_to_database(); //add to database

                                //set to true the interaction then the user of the tahoe will know that someone has changed the light by using the server
                                Program.light_interaction = true;
                               
                            }
                            else if (HTTPRequest[i] == "switchalloff") //if in the request we find that so we swithoff all the light
                            {
                                Program.stateLed = false;
                                Program.stateLeds = false;
                                Program.leds.Write(Program.stateLeds);
                                Program.led.Write(Program.stateLed);

                              
                            }


                            else if (HTTPRequest[i] == "changelight1") //so we change light in room 2
                            {
                                Program.stateLeds = !Program.stateLeds;
                                Program.leds.Write(Program.stateLeds);
                                DataBase.android_user_add_light2_state_to_database();//add to databse
                                container2 = Program.stateLeds;
                                Program.light_interaction = true;
                               
    
                            }

                            else if (HTTPRequest[i] == "all") //we return the status of all the Home
                            {
                                displayTemp = Heat_Control.temperature.ReadTemperature();
                                container = Program.stateLed;
                                container2 = Program.stateLeds;
                                container3 = Program.inputPort.Read() == false;
                                //We return a String in JSON array Format
                                String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n" +
                   "[{\"id\":\"0\",\"floor\":\"0\",\"type\":\"0\",\"lightOn\":\"" + container + "\",\"temperature\":\"" + displayTemp.ToString() + "\",\"doorOpen\":\"true\"}," +
                       "{\"id\":\"1\",\"floor\":\"0\",\"type\":\"1\",\"lightOn\":\"" + container2 + "\",\"temperature\":\"" + displayTemp.ToString() + "\",\"doorOpen\":\"" + container3 + "\"}]";

                               
                                

                                byte[] buf = Encoding.UTF8.GetBytes(s);
                                int offset = 0;
                                int ret = 0;
                                int len = buf.Length;
                                while (len > 0)
                                {
                                    ret = newSock.Send(buf, offset, len,
                                                              SocketFlags.None);
                                    len -= ret;
                                    offset += ret;
                                }

                            }
                            
                                //check all the possibilities for the temmperature. It's long but
                                //we are working to find something more soft !! Maybe For an Update we will find something better !!
                            else if ((HTTPRequest[i] == "setmintemp=-5") || (HTTPRequest[i] == "setmintemp=-4") || (HTTPRequest[i] == "setmintemp=-3") || (HTTPRequest[i] == "setmintemp=-2") || (HTTPRequest[i] == "setmintemp=-1") || (HTTPRequest[i] == "setmintemp=00") || (HTTPRequest[i] == "setmintemp=01") || (HTTPRequest[i] == "setmintemp=02") || (HTTPRequest[i] == "setmintemp=03") || (HTTPRequest[i] == "setmintemp=04") || (HTTPRequest[i] == "setmintemp=05") || (HTTPRequest[i] == "setmintemp=06") || (HTTPRequest[i] == "setmintemp=07") || (HTTPRequest[i] == "setmintemp=08") || (HTTPRequest[i] == "setmintemp=09") || (HTTPRequest[i] == "setmintemp=10") || (HTTPRequest[i] == "setmintemp=11") || (HTTPRequest[i] == "setmintemp=12") || (HTTPRequest[i] == "setmintemp=13") || (HTTPRequest[i] == "setmintemp=14") || (HTTPRequest[i] == "setmintemp=15") || (HTTPRequest[i] == "setmintemp=16") || (HTTPRequest[i] == "setmintemp=17") || (HTTPRequest[i] == "setmintemp=18") || (HTTPRequest[i] == "setmintemp=19") || (HTTPRequest[i] == "setmintemp=20") || (HTTPRequest[i] == "setmintemp=21") || (HTTPRequest[i] == "setmintemp=22") || (HTTPRequest[i] == "setmintemp=23") || (HTTPRequest[i] == "setmintemp=24") || (HTTPRequest[i] == "setmintemp=25") || (HTTPRequest[i] == "setmintemp=26") || (HTTPRequest[i] == "setmintemp=27") || (HTTPRequest[i] == "setmintemp=28") || (HTTPRequest[i] == "setmintemp=29") || (HTTPRequest[i] == "setmintemp=30") || (HTTPRequest[i] == "setmintemp=31") || (HTTPRequest[i] == "setmintemp=32") || (HTTPRequest[i] == "setmintemp=33") || (HTTPRequest[i] == "setmintemp=34") || (HTTPRequest[i] == "setmintemp=35") || (HTTPRequest[i] == "setmintemp=36") || (HTTPRequest[i] == "setmintemp=37") || (HTTPRequest[i] == "setmintemp=38") || (HTTPRequest[i] == "setmintemp=39") || (HTTPRequest[i] == "setmintemp=40"))
                            {
                                string copyofrequest = HTTPRequest[i]; //we make a copy of the right request 
                                //we try to find the "=" then we can find the number and truy to convert it in to an Integer
                                for (int w = 0; w < copyofrequest.Length; w++) 
                                {
                                    if (copyofrequest[w] == '=')
                                    {
                                        //we receive always a number on two digits then we have two parts for our number !
                                        char part_one = copyofrequest[w + 1]; 
                                        char part_two = copyofrequest[w + 2];
                                        if (part_one != '-') //if it's  not a negative number 
                                        {
                                            //convert to int
                                            int part_one_int = Convert.ToInt32(part_one.ToString());
                                            int part_two_int = Convert.ToInt32(part_two.ToString());
                                            //we set min_temp_set to true in order to trigger the alarm
                                            Program.min_temp_set = true;

                                            //we put them together to have a full number 
                                            Program.min_temp = (part_one_int * 10) + part_two_int;

                                            //give some memory in order to allow the Alarm thread to know those new value
                                            Thread.Sleep(5);

                                        }
                                        else if (part_one == '-') //if it's a negative number
                                        {
                                            int part_two_int = Convert.ToInt32(part_two.ToString());
                                            //we set min_temp_set to true in order to trigger the alarm
                                            Program.min_temp_set = true;

                                            Program.min_temp = 0 - (part_two_int);
  
                                            //give some memory to the system
                                            Thread.Sleep(50);

                                        }


                                    }
                                }
                            }

                              //same thing as above except that it's for the max temperature
                            else if ((HTTPRequest[i] == "setmaxtemp=-5") || (HTTPRequest[i] == "setmaxtemp=-4") || (HTTPRequest[i] == "setmaxtemp=-3") || (HTTPRequest[i] == "setmaxtemp=-2") || (HTTPRequest[i] == "setmaxtemp=-1") || (HTTPRequest[i] == "setmaxtemp=00") || (HTTPRequest[i] == "setmaxtemp=01") || (HTTPRequest[i] == "setmaxtemp=02") || (HTTPRequest[i] == "setmaxtemp=03") || (HTTPRequest[i] == "setmaxtemp=04") || (HTTPRequest[i] == "setmaxtemp=05") || (HTTPRequest[i] == "setmaxtemp=06") || (HTTPRequest[i] == "setmaxtemp=07") || (HTTPRequest[i] == "setmaxtemp=08") || (HTTPRequest[i] == "setmaxtemp=09") || (HTTPRequest[i] == "setmaxtemp=10") || (HTTPRequest[i] == "setmaxtemp=11") || (HTTPRequest[i] == "setmaxtemp=12") || (HTTPRequest[i] == "setmaxtemp=13") || (HTTPRequest[i] == "setmaxtemp=14") || (HTTPRequest[i] == "setmaxtemp=15") || (HTTPRequest[i] == "setmaxtemp=16") || (HTTPRequest[i] == "setmaxtemp=17") || (HTTPRequest[i] == "setmaxtemp=18") || (HTTPRequest[i] == "setmaxtemp=19") || (HTTPRequest[i] == "setmaxtemp=20") || (HTTPRequest[i] == "setmaxtemp=21") || (HTTPRequest[i] == "setmaxtemp=22") || (HTTPRequest[i] == "setmaxtemp=23") || (HTTPRequest[i] == "setmaxtemp=24") || (HTTPRequest[i] == "setmaxtemp=25") || (HTTPRequest[i] == "setmaxtemp=26") || (HTTPRequest[i] == "setmaxtemp=27") || (HTTPRequest[i] == "setmaxtemp=28") || (HTTPRequest[i] == "setmaxtemp=29") || (HTTPRequest[i] == "setmaxtemp=30") || (HTTPRequest[i] == "setmaxtemp=31") || (HTTPRequest[i] == "setmaxtemp=32") || (HTTPRequest[i] == "setmaxtemp=33") || (HTTPRequest[i] == "setmaxtemp=34") || (HTTPRequest[i] == "setmaxtemp=35") || (HTTPRequest[i] == "setmintemp=36") || (HTTPRequest[i] == "setmaxtemp=37") || (HTTPRequest[i] == "setmaxtemp=38") || (HTTPRequest[i] == "setmaxtemp=39") || (HTTPRequest[i] == "setmaxtemp=40"))
                            {


                                string copyofrequestmax = HTTPRequest[i];
                                for (int w = 0; w < copyofrequestmax.Length; w++)
                                {
                                    if (copyofrequestmax[w] == '=')
                                    {
                                        char part_one = copyofrequestmax[w + 1];
                                        char part_two = copyofrequestmax[w + 2];
                                        if (part_one != '-')
                                        {
                                            int part_one_int = Convert.ToInt32(part_one.ToString());
                                            int part_two_int = Convert.ToInt32(part_two.ToString());
                                            //we set max_temp_set to true in order to trigger the alarm
                                            Program.max_temp_set = true;
                                            Program.max_temp = (part_one_int * 10) + part_two_int;

                                            //give some memory to the system
                                            Thread.Sleep(100);

                                            String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n";
                                            byte[] buf = Encoding.UTF8.GetBytes(s);
                                            int offset = 0;
                                            int ret = 0;
                                            int len = buf.Length;
                                            while (len > 0)
                                            {
                                                ret = newSock.Send(buf, offset, len, SocketFlags.None);
                                                len -= ret;
                                                offset += ret;
                                            }


                                        }
                                        else if (part_one == '-')
                                        {
                                            int part_two_int = Convert.ToInt32(part_two.ToString());
                                            //we set max_temp_set to true in order to trigger the alarm
                                            Program.max_temp_set = true;
                                            Program.max_temp = 0 - (part_two_int);

                                            //give some memory to the system
                                            Thread.Sleep(100);

                                            String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n";
                                            byte[] buf = Encoding.UTF8.GetBytes(s);
                                            int offset = 0;
                                            int ret = 0;
                                            int len = buf.Length;
                                            while (len > 0)
                                            {
                                                ret = newSock.Send(buf, offset, len, SocketFlags.None);
                                                len -= ret;
                                                offset += ret;
                                            }
                                        }

                                    }
                                }
                            }
                            else if (HTTPRequest[i] == "checktempalarm") //check if there is alarm or not 
                            {

                                DataBase.android_user_add_temperature_state_to_database(); //add temperature to database
                                if ((Program.alarm_min_reached == false) && (Program.alarm_max_reached == false)) //if the limits are not reached 
                                {
                                    //then we return an empty string
                                    String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n";
                                    byte[] buf = Encoding.UTF8.GetBytes(s);
                                    int offset = 0;
                                    int ret = 0;
                                    int len = buf.Length;
                                    while (len > 0)
                                    {
                                        ret = newSock.Send(buf, offset, len, SocketFlags.None);
                                        len -= ret;
                                        offset += ret;
                                    }
                                }
                                else if ((Program.alarm_min_reached == true)) //if temperature minimum is reached then we return 0
                                {
                                    String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n0";
                                    byte[] buf = Encoding.UTF8.GetBytes(s);
                                    int offset = 0;
                                    int ret = 0;
                                    int len = buf.Length;
                                    while (len > 0)
                                    {
                                        ret = newSock.Send(buf, offset, len, SocketFlags.None);
                                        len -= ret;
                                        offset += ret;
                                    }
                                }
                                else if ((Program.alarm_max_reached == true))  //if temperature maximum is reached then we return 1
                                {
                                    String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n1";
                                    byte[] buf = Encoding.UTF8.GetBytes(s);
                                    int offset = 0;
                                    int ret = 0;
                                    int len = buf.Length;
                                    while (len > 0)
                                    {
                                        ret = newSock.Send(buf, offset, len, SocketFlags.None);
                                        len -= ret;
                                        offset += ret;
                                    }
                                }
                                Program.alarm_min_reached = false;
                                Program.alarm_max_reached = false;
                            }




                                }
                            }

                        }
                        newSock.Close();  //close the socket


                    }

                }


            }
        }
    
